#ifndef SSHSESSION_H
#define SSHSESSION_H

#include <QObject>
#include <QString>
#include <QByteArray>
#include <QThread>
#include <QMutex>
#include <QWaitCondition>
#include <QTimer>
#include <QDateTime>
#include <sys/types.h>
#include <libssh2.h>
#include <libssh2_sftp.h>

#include "sshmanager.h"

/**
 * @brief SSH会话类
 *
 * 管理单个SSH连接的完整生命周期
 * 支持shell、SFTP、端口转发等功能
 */
class SshSession : public QThread
{
    Q_OBJECT

    friend class SshManager;

public:
    enum SessionState {
        Disconnected,
        Connecting,
        Connected,
        Authenticating,
        Authenticated,
        Ready,
        Error
    };

    struct SftpFile {
        QString path;
        QString name;
        qint64 size;
        bool isDirectory;
        QDateTime lastModified;
        QString permissions;
        QString owner;
        QString group;
    };

    explicit SshSession(const SshManager::ConnectionConfig &config, const QString &sessionId, QObject *parent = nullptr);
    ~SshSession();

    // 连接管理
    bool connectTo();
    void disconnect();
    bool isConnected() const;
    SessionState state() const;

    // 认证方式
    bool authenticateWithPassword(const QString &password);
    bool authenticateWithKey(const QString &privateKeyPath, const QString &passphrase = "");
    // bool authenticateWithAgent(); // 暂时禁用 - libssh2版本不支持
    // bool authenticateWithKeyboardInteractive(); // 暂时禁用 - libssh2版本不支持

    // Shell操作
    bool openShell();
    bool executeCommand(const QString &command, QString &output);
    bool sendShellCommand(const QString &command);
    bool sendShellData(const QByteArray &data);

    // SFTP操作
    bool openSftp();
    bool closeSftp();
    QList<SftpFile> listDirectory(const QString &path);
    bool uploadFile(const QString &localPath, const QString &remotePath);
    bool downloadFile(const QString &remotePath, const QString &localPath);
    bool deleteFile(const QString &remotePath);
    bool createDirectory(const QString &path);
    bool removeDirectory(const QString &path);
    bool renameFile(const QString &oldPath, const QString &newPath);

    // 端口转发
    bool setupPortForwarding(int localPort, const QString &remoteHost, int remotePort);

    // 获取连接信息
    QString sessionId() const;
    QString host() const;
    int port() const;
    QString username() const;
    QString lastError() const;

    // 获取内部会话（供SftpManager使用）
    LIBSSH2_SESSION* sshSession() const { return m_sshSession; }

signals:
    void stateChanged(SessionState state);
    void connected();
    void disconnected();
    void error(const QString &error);
    void shellOutput(const QByteArray &data);
    void shellError(const QByteArray &data);
    void commandFinished(const QString &command, int exitCode);
    void fileTransferProgress(const QString &filename, qint64 transferred, qint64 total);
    void directoryListed(const QString &path, const QList<SftpFile> &files);

private slots:
    void run() override;
public slots:
    void keepAlive();

private:
    SshManager::ConnectionConfig m_config;
    QString m_sessionId;
    SessionState m_state;
    QString m_lastError;

    // libssh2相关
    LIBSSH2_SESSION *m_sshSession;
    LIBSSH2_CHANNEL *m_shellChannel;
    LIBSSH2_SFTP *m_sftpSession;
    int m_socket;

    // 线程相关
    mutable QMutex m_mutex;
    QWaitCondition m_waitCondition;
    bool m_running;

    // 定时器相关
    QTimer *m_keepAliveTimer;

    // 内部方法
    bool createSocket();
    bool initializeSession();
    bool handshake();
    bool authenticate();
    void cleanup();
    void setState(SessionState state);
    void setLastError(const QString &error);

    // Shell处理
    void processShellOutput();
    int waitForSocket(int timeout_ms = 1000);
    int waitForSession(int timeout_ms = 1000);

    // SFTP内部方法
    LIBSSH2_SFTP_ATTRIBUTES* getSftpAttributes(const QString &path);
    SftpFile sftpAttributesToFile(const QString &path, const LIBSSH2_SFTP_ATTRIBUTES *attrs);
};

#endif // SSHSESSION_H
